package com.icesoft.base.manager.service.security;

import com.icesoft.base.manager.base.BaseService;
import com.icesoft.base.manager.entity.security.RelSysRoleAuthority;
import com.icesoft.base.manager.entity.security.SysApiAuthority;
import com.icesoft.base.manager.entity.security.SysMenu;
import com.icesoft.base.manager.entity.security.SysRole;
import com.icesoft.base.manager.security.config.ApiMatchAuthority;
import com.icesoft.base.manager.security.config.SecurityProperty;
import com.icesoft.base.manager.security.config.WebSecurityConfig;
import com.icesoft.core.dao.criteria.QueryBuilder;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@CacheConfig(cacheNames = SysApiAuthorityService.CACHE_GROUP)
@AllArgsConstructor
public class SysApiAuthorityService extends BaseService<SysApiAuthority> {
    public static final String CACHE_GROUP = "simpleAuthorityService";
    public static final String KEY_FIND_ALL_AUTHORITY = "'findAllAuthority'";

    private final SysMenuService sysMenuService;
    private final SysRoleService sysRoleService;
    public List<SysApiAuthority> findByGroupId(int groupId) {
        return find(QueryBuilder.get("groupId", groupId));
    }

    public SysApiAuthority findByGroupIdAndName(int groupId, String name) {
        return unique(QueryBuilder.get("groupId", groupId).andEq("name", name));
    }

    public void deleteByGroupId(int groupId) {
        delete(QueryBuilder.get("groupId", groupId));
    }

    public Set<String> findAuthorityByRoleId(int roleId) {
        return findByRoleId(roleId).stream().map(SysApiAuthority::getAuthority).collect(Collectors.toSet());
    }

    private static String menuUrlPattern(String url) {
        return url.substring(0, url.lastIndexOf("/") + 1) + "**.html";
    }

    public List<SysApiAuthority> findByRoleId(int roleId) {
        QueryBuilder queryBuilder = QueryBuilder.get()
                .joinOn(RelSysRoleAuthority.class, "ra", "authorityId")
                .andEq("ra.roleId", roleId);
        return find(queryBuilder);
    }

    public Set<ApiMatchAuthority> findUrlsByUserId(int userId){
        Set<ApiMatchAuthority> authorities = new HashSet<>();
        List<SysRole> sysRoleList = sysRoleService.findByUserId(userId);
        for (SysRole s : sysRoleList) {
            for (SysRole sysRole : sysRoleList) {
                authorities.add(new ApiMatchAuthority(sysRole.getName(), findAuthorityByRoleId(sysRole.getId())));
            }
            authorities.add(new ApiMatchAuthority("menuUrlAuthority",sysMenuService.findByRoleId(s.getId()).stream().map(SysMenu::getUrl)
                    .filter(StringUtils::isNotBlank).map(SysApiAuthorityService::menuUrlPattern).collect(Collectors.toSet())));
        }
        return authorities;
    }

}
